package com.witmore.skyline.web.service.third.yjx.client;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.witmore.skyline.web.annotation.ApiCache;
import com.witmore.skyline.web.enums.TimePrecision;
import com.witmore.skyline.web.service.third.constants.ApiClientCommonConstant;
import com.witmore.skyline.web.service.third.yjx.dto.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Service;

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

import static java.lang.String.format;

/**
 * Description: ApiDeviceOilClient 第三方接口调用-设备相关接口
 * Author: 豆子高
 * Date: 2025/2/25 16:26
 */
@Slf4j
@Service
public class ApiDeviceOilClient {

    /**
     * 获取设备油位百分比接口（已废弃，请使用 V2 版本）
     */
    public List<DeviceOilDTO> fetchDeviceOilPercent(String deviceSn, String startTime, String endTime) {
        // 对startTime 和 endTime 进行编码
        startTime = URLEncoder.encode(startTime, StandardCharsets.UTF_8);
        endTime = URLEncoder.encode(endTime, StandardCharsets.UTF_8);
        String urlString = format(ApiClientCommonConstant.API_PREFIX + ApiClientCommonConstant.GET_DEVICE_OIL_PERCENT_PATH,
                TokenCache.getToken(), deviceSn, startTime, endTime);
        String responseResult = ApiClient.responseHandle(urlString, "获取设备油位百分比接口");
        if (ObjectUtils.isEmpty(responseResult)) {
            log.info("api 获取设备油位百分比接口调用结果为空");
            return new ArrayList<>();
        }
        return JSONObject.parseArray(responseResult, DeviceOilDTO.class);
    }

    /**
     * 获取设备加油数据
     */
    @ApiCache(
        expireMinutes = 5,
        keyParams = {"deviceSn", "startTime", "endTime"},
        timeParams = {"startTime", "endTime"},
        timePrecision = TimePrecision.CACHE_WINDOW
    )
    public AddOilDTO fetchDeviceRefuel(String deviceSn, String startTime, String endTime) {
        startTime = URLEncoder.encode(startTime, StandardCharsets.UTF_8);
        endTime = URLEncoder.encode(endTime, StandardCharsets.UTF_8);
        String urlString = format(ApiClientCommonConstant.API_PREFIX + ApiClientCommonConstant.GET_DEVICE_REFUEL_PATH,
                TokenCache.getToken(), deviceSn, startTime, endTime);
        String responseResult = ApiClient.responseHandle(urlString, "获取设备加油数据接口");
        if (ObjectUtils.isEmpty(responseResult)) {
            log.info("api 获取设备加油数据接口调用结果为空");
            return null;
        }
        return JSONObject.parseObject(responseResult, AddOilDTO.class);
    }

    /**
     * 获取设备用油量接口
     */
    @ApiCache(
        expireMinutes = 5,
        keyParams = {"deviceSn", "startTime", "endTime"},
        timeParams = {"startTime", "endTime"},
        timePrecision = TimePrecision.CACHE_WINDOW
    )
    public List<DeviceOilConsumptionDTO> fetchDeviceFuelConsumption(String deviceSn, String startTime, String endTime) {
        startTime = URLEncoder.encode(startTime, StandardCharsets.UTF_8);
        endTime = URLEncoder.encode(endTime, StandardCharsets.UTF_8);
        String urlString = format(ApiClientCommonConstant.API_PREFIX + ApiClientCommonConstant.GET_DEVICE_FUEL_CONSUMPTION_PATH,
                TokenCache.getToken(), deviceSn, startTime, endTime);
        String responseResult = ApiClient.responseHandle(urlString, "获取设备用油量接口");
        if (ObjectUtils.isEmpty(responseResult)) {
            log.info("api 获取设备用油量接口调用结果为空");
            return null;
        }
        return JSONObject.parseArray(responseResult, DeviceOilConsumptionDTO.class);
    }

    /**
     * 获取设备平均用油量接口
     */
    @ApiCache(
        expireMinutes = 5,
        keyParams = {"deviceSn", "startTime", "endTime"},
        timeParams = {"startTime", "endTime"},
        timePrecision = TimePrecision.CACHE_WINDOW
    )
    public List<DeviceAvgFuelConsumptionDTO> fetchDeviceAverageFuelConsumption(String deviceSn, String startTime, String endTime) {
        startTime = URLEncoder.encode(startTime, StandardCharsets.UTF_8);
        endTime = URLEncoder.encode(endTime, StandardCharsets.UTF_8);
        String urlString = format(ApiClientCommonConstant.API_PREFIX + ApiClientCommonConstant.GET_DEVICE_AVERAGE_FUEL_CONSUMPTION_PATH,
                TokenCache.getToken(), deviceSn, startTime, endTime);
        String responseResult = ApiClient.responseHandle(urlString, "获取设备平均用油量接口");
        if (ObjectUtils.isEmpty(responseResult)) {
            log.info("api 获取设备平均用油量接口调用结果为空");
            return null;
        }
        return JSONObject.parseArray(responseResult, DeviceAvgFuelConsumptionDTO.class);
    }

    /**
     * 分页获取设备油位百分比接口（不带缓存）
     * @param deviceSn 设备编号
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @param page 页码（从1开始）
     * @param size 每页大小（最大2000）
     * @return 油位数据分页响应，失败返回null
     */
    public ApiResponse<List<DeviceOilDTO>> fetchDeviceOilPercentWithPage(String deviceSn, String startTime, String endTime, int page, int size) {
        startTime = URLEncoder.encode(startTime, StandardCharsets.UTF_8);
        endTime = URLEncoder.encode(endTime, StandardCharsets.UTF_8);
        String urlString = format(ApiClientCommonConstant.API_PREFIX + ApiClientCommonConstant.GET_DEVICE_OIL_PERCENT_PATH + "&page=%d&size=%d",
                TokenCache.getToken(), deviceSn, startTime, endTime, page, size);

        // 直接调用 httpConnection 获取响应字符串（不走 responseHandle，因为需要 page 信息）
        String responseStr = ApiClient.httpConnection(urlString, ApiClientCommonConstant.METHOD_GET);

        if (ObjectUtils.isEmpty(responseStr)) {
            log.error("api 分页获取设备油位百分比接口调用结果为空, page={}, size={}", page, size);
            return null;
        }

        // 解析完整响应（包含 result 和 page）
        ApiResponse<List<DeviceOilDTO>> apiResponse = JSONObject.parseObject(responseStr,
                new TypeReference<>() {
                });

        if (apiResponse == null || 800 != apiResponse.getCode()) {
            log.error("api 分页获取设备油位百分比接口调用失败, page={}, size={}, code={}, response={}",
                    page, size, apiResponse != null ? apiResponse.getCode() : -1, responseStr);
            return null;
        }

        return apiResponse;
    }

}
